#include "LinkStack.h"
#include "LinkQueue.h"
#include <MyString.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <StdFile.h>

#define StopSize 3
#define CLEARSCANF while(getchar() != '\n');
#define PerPrice 5 //停车场单价

MyStr GetTimeStr(const long t)
{
    struct tm * m = gmtime(&t);
    INITSTR(str);
    ResizeSting(&str,100);
    sprintf(str.string,"%d年%d月%d日 %d时%d分%d秒",m->tm_year + 1900,m->tm_mon + 1,m->tm_mday,(m->tm_hour + 8) % 24,m->tm_min,m->tm_sec);
    return str;
}


//定义对象----车
typedef struct
{
    //车牌号
    MyStr name;
    //到达时间
    long arriveTime;
    //离开时间
    long leaveTime;
}Car;

void PrintCar(void *ptr)
{
    Car* c = (Car *)ptr;
    MyStr t = GetTimeStr(c->arriveTime);
    printf("车牌:|%s|,到达时间:|%s|\n",c->name.string,t.string);
    ClearString(&t);
}

//创建对象----车
Car *CreateCar(const char *name,double arriveTime)
{
    Car * c = (Car *)malloc(sizeof(Car));
    if(c == NULL)
    {
        printf("创建对象失败!\n");
        return NULL;
    }
    c->name = GetString(name);
    c->arriveTime = arriveTime;
}
void FreeCar(void *ptr)
{
    Car *c = (Car*)ptr;
    ClearString(&c->name);
    free(c);
}

static long price = 0.0;

void WriteCarToFile(Car *c)
{
    char fileContent[100] = {0};
    sprintf(fileContent,"%s %ld %ld %ld\n",c->name.string,c->arriveTime,c->leaveTime,price);
    AppendToFile("carstop.txt",fileContent,strlen(fileContent));
}


//来车
void ComeCar(LStack *carStop,LQueue *pavement)
{
    //创建一辆车
    printf("请输入车牌号:");
    char carName[100] = {0};
    scanf("%s",carName);
    CLEARSCANF;

    long t = time(NULL);

    Car *newCar = CreateCar(carName,t);
    if(newCar == NULL)
        return;
    
    
    //车准备进入停车场
    //停车场没停满
    if(GetStackLen(carStop) < StopSize)
    {
        //压入停车场的栈中
        SPush(carStop,newCar);
        printf("当前停车场未满,车辆|%s|停在了停车场的第%d个位置\n",newCar->name.string,GetStackLen(carStop));
    }
    //停车场已满
    else
    {
        //压入便道的队列中
        QPush(pavement,newCar);
        printf("当前停车场已满,车辆|%s|停在了便道的%d个位置\n",newCar->name.string,GetQueueLen(pavement));
    }
}

//车辆离开
void LeaveCar(LStack* carStop,LQueue* pavement)
{
    printf("请输入要离开的车牌:");
    char carName[100] = {0};
    scanf("%s",carName);
    CLEARSCANF;

    //构建临时栈
    LStack *tempS = InitLStack();
    double leaveTime = 0.0;
    int flag = 0;
    while(IsStackEmpty(carStop) == false)
    {
        Car *c = (Car*)*GetSTop(carStop);
        //找到了这辆车
        if(IsEqual(&c->name,carName) == true)
        {
            flag = 1;
            c->leaveTime = time(NULL);
            leaveTime = c->leaveTime;

            

            
            if((c->leaveTime-c->arriveTime) <= 3600)
                price = PerPrice;
            else    price = (c->leaveTime-c->arriveTime) * PerPrice / 3600;

            printf("车辆|%s|在|%s|到达停车场,在|%s|离开停车场,总费用是%ld\n",
                c->name.string,GetTimeStr(c->arriveTime).string,GetTimeStr(c->leaveTime).string,price);
            WriteCarToFile(c);
            //真正离开停车场
            SPop(carStop);
            //清除车辆
            FreeCar(c);
            break; 
        }    
        //车辆进入临时栈,从停车场出栈
        SPush(tempS,c);
        SPop(carStop);
    }
    if(flag == 0)
    {
        printf("没找到这辆车!\n");
    }

    //找完以后,把车从临时栈开回停车场的栈
    while(IsStackEmpty(tempS) == false)
    {
        SPush(carStop,*GetSTop(tempS));
        SPop(tempS);
    }
    ClearLStack(tempS,NULL);

    //有车离开并且便道上有车在等待
    if(GetStackLen(carStop) < StopSize && IsQueueEmpty(pavement) == false)
    {
        //便道上第一辆车出队列
        Car *frontC = (Car*)*GetQFront(pavement);
        QPop(pavement);

        //到达时间是上一辆车的离开时间
        frontC->arriveTime = leaveTime;
        printf("车辆|%s|从便道上进入停车场,时间是|%s|\n",frontC->name.string,GetTimeStr(frontC->arriveTime).string);
        //车辆进入停车场
        SPush(carStop,frontC);
    }
}

void DisplayCarStop()
{
    long totalMoney = 0;
    MyStrList list = GetLineFromFile("carstop.txt");
    for(int i = 0 ;i < list.len; i++)
    {
        Car c = {NULL,0,0};
        ResizeSting(&c.name,100);
        long money = 0;
        sscanf(list.StringList[i].string,"%s %ld %ld %ld",c.name.string,&c.arriveTime,&c.leaveTime,&money);
        printf("车牌:|%s|,到达时间:|%s|,离开时间|%s| 收费:%ld\n",c.name.string,GetTimeStr(c.arriveTime).string,GetTimeStr(c.leaveTime).string,money);
        totalMoney += money;    
    }
    printf("总收入:%ld￥\n",totalMoney);
}








int main()
{
    //定义一个停车场
    LStack *carStop = InitLStack();

    //定义一个便道
    LQueue *pavement = InitLQueue();

    //判断文件是否存在
    if(IsFileExist("carstop.txt") == false)
    {
        CreateNewFile("carstop.txt");
    }

    //逻辑界面
    while(1)
    {
        printf("=================停车场====================\n");
        printf("1.车辆进入停车场\n");
        printf("2.车辆离开停车场\n");
        printf("3.显示停车场信息\n");
        printf("4.显示便道信息\n");
        printf("5.显示停车场出车流水信息\n");
        printf("6.退出\n");
        printf("===========================================\n");

        int choice = 0;
        scanf("%d",&choice);
        CLEARSCANF;

        switch (choice)
        {
        case 1:
            system("clear");
            ComeCar(carStop,pavement);
            break;
        case 2:
            system("clear");
            LeaveCar(carStop,pavement);
            break;
        case 3:
            system("clear");
            TravelLStack(carStop,PrintCar);
            break;
        case 4:
            system("clear");
            TravelLQueue(pavement,PrintCar);
            break;
        case 5:
            DisplayCarStop();
            break;
        case 6:
            ClearLStack(carStop,FreeCar);
            ClearLQueue(pavement,FreeCar);
            printf("退出系统中...\n");
            sleep(1);
            exit(0);
        default:
            break;
        }
    }

    return 0;
}